﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AutomatedTestDataManagement.Models;
using System.Collections;

namespace AutomatedTestDataManagement.Controllers
{
    public class TestStepController : Controller
    {
        private ApplicationTestDataEntities db = new ApplicationTestDataEntities();

        //
        // GET: /TestStep/

        public ActionResult Index()
        {
            var teststeps = db.TestSteps.Include(t => t.StepKind);
            return View(teststeps.ToList());
        }

        //
        // GET: /TestStep/Details/5

        public ActionResult Details(int id = 0)
        {
            TestStep teststep = db.TestSteps.Find(id);
            if (teststep == null)
            {
                return HttpNotFound();
            }
            return View(teststep);
        }

        //
        // GET: /TestStep/Create

        public ActionResult Create(int id = 0, int scenarioID = 0, int SuiteID = 0)
        {
            if (id != 0) { ViewBag.TestID = id; }
            if (scenarioID != 0) { ViewBag.ScenarioID = scenarioID; }
            if (SuiteID != 0) { ViewBag.SuiteID = SuiteID; }
            ViewBag.StepKindID = new SelectList(db.StepKinds, "StepKindID", "StepKind1");
            return View();
        }

        //
        // POST: /TestStep/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(TestStep teststep)
        {
            var testID = Request.Form["TestID"];
            var scenarioID = Request.Form["ScenarioID"];
            var suiteID = Request.Form["SuiteID"];

            if (ModelState.IsValid)
            {
                db.TestSteps.Add(teststep);
                db.SaveChanges();

                if (testID != null)
                {
                    if (scenarioID != null)
                    {
                        if (suiteID != null)
                        {
                            return RedirectToAction("Edit", "Test", new { id = testID, scenarioID = scenarioID, suiteID = suiteID });
                        }
                        else
                        {
                            return RedirectToAction("Edit", "Test", new { id = testID, scenarioID = scenarioID });
                        }
                    }
                    else
                    {
                        return RedirectToAction("Edit", "Test", new { id = testID });
                    }
                }
                else
                {
                    return RedirectToAction("Index");
                }
            }

            if (testID != null) { ViewBag.TestID = testID; }
            if (scenarioID != null) { ViewBag.ScenarioID = scenarioID; }
            if (suiteID != null) { ViewBag.SuiteID = suiteID; }

            ViewBag.StepKindID = new SelectList(db.StepKinds, "StepKindID", "StepKind1", teststep.StepKindID);
            return View(teststep);
        }

        //
        // POST: /TestStep/CreatePartial

        [HttpPost]
        public ActionResult CreatePartial(TestStep teststep)
        {

            var testID = Request.Form["TestID"];
            var scenarioID = Request.Form["ScenarioID"];
            var suiteID = Request.Form["SuiteID"];

            if (ModelState.IsValid && teststep.DataID > 0)
            {
                db.TestSteps.Add(teststep);
                db.SaveChanges();
                if (testID != null)
                {
                    if (scenarioID != null)
                    {
                        if (suiteID != null)
                        {
                            return RedirectToAction("Edit", "Test", new { id = testID, scenarioID = scenarioID, suiteID = suiteID });
                        }
                        else
                        {
                            return RedirectToAction("Edit", "Test", new { id = testID, scenarioID = scenarioID });
                        }
                    }
                    else
                    {
                        return RedirectToAction("Edit", "Test", new { id = testID });
                    }
                }
                else
                {
                    return RedirectToAction("Index");
                }
            }

            if (testID != null) { ViewBag.TestID = testID; }
            if (scenarioID != null) { ViewBag.ScenarioID = scenarioID; }
            if (suiteID != null) { ViewBag.SuiteID = suiteID; }
            SelectList DataView = new SelectList(ViewToUse(teststep.StepKindID), "text", "value", "");
            ViewBag.StepKindID = new SelectList(db.StepKinds, "StepKindID", "StepKind1", teststep.StepKindID);
            ViewBag.DataList = DataView;
            return View("Create", teststep);
        }
        //
        // GET: /TestStep/Edit/5

        public ActionResult Edit(int id = 0, int testID = 0, int scenarioID = 0, int suiteID = 0)
        {
            TestStep teststep = db.TestSteps.Find(id);
            if (teststep == null)
            {
                return HttpNotFound();
            }
            if (testID != 0)
            {
                ViewBag.TestID = testID;
            }
            if (scenarioID != 0)
            {
                ViewBag.ScenarioID = scenarioID;
            }
            if (suiteID != 0)
            {
                ViewBag.SuiteID = suiteID;
            }
            SelectList DataView = new SelectList(ViewToUse(teststep.StepKindID), "text", "value", teststep.DataID);
            ViewBag.DataList = DataView;
            ViewBag.StepKindID = new SelectList(db.StepKinds, "StepKindID", "StepKind1", teststep.StepKindID);
            return View(teststep);
        }

        //
        // POST: /TestStep/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(TestStep teststep)
        {
            var testID = Request.Form["TestID"];
            var scenarioID = Request.Form["ScenarioID"];
            var suiteID = Request.Form["SuiteID"];

            if (ModelState.IsValid)
            {
                db.Entry(teststep).State = EntityState.Modified;
                db.SaveChanges();

                if (testID != null)
                {
                    if (scenarioID != null)
                    {
                        if (suiteID != null)
                        {
                            return RedirectToAction("Edit", "Test", new { id = testID, scenarioID = scenarioID, suiteID = suiteID });
                        }
                        else
                        {
                            return RedirectToAction("Edit", "Test", new { id = testID, scenarioID = scenarioID });
                        }
                    }
                    else
                    {
                        return RedirectToAction("Edit", "Test", new { id = testID });
                    }
                }
                else
                {
                    return RedirectToAction("Index");
                }
            }
            if (testID != null) { ViewBag.TestID = testID; }
            if (scenarioID != null) { ViewBag.ScenarioID = scenarioID; }
            if (suiteID != null) { ViewBag.SuiteID = suiteID; }
            SelectList DataView = new SelectList(ViewToUse(teststep.StepKindID), "text", "value", teststep.DataID);
            ViewBag.DataList = DataView;
            ViewBag.StepKindID = new SelectList(db.StepKinds, "StepKindID", "StepKind1", teststep.StepKindID);
            return View(teststep);
        }

        //
        // GET: /TestStep/Delete/5

        public ActionResult Delete(int id = 0)
        {
            TestStep teststep = db.TestSteps.Find(id);
            if (teststep == null)
            {
                return HttpNotFound();
            }
            if (teststep.TestTestSteps.Count > 0)
            {
                ModelState.AddModelError("", "This test step is used in at least one test. You must remove it from all tests before deleting");
            }
            return View(teststep);
        }

        //
        // POST: /TestStep/Delete/5

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            TestStep teststep = db.TestSteps.Find(id);
            db.TestSteps.Remove(teststep);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        public ActionResult GetDataList(int id)
        {
            var dataView = ViewToUse(Convert.ToInt32(id));
            var test = this.Json(dataView, JsonRequestBehavior.AllowGet);
            return this.Json(new { DataID = dataView }, JsonRequestBehavior.AllowGet);
        }
        
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        private SelectList ViewToUse(int skid)
        {
            // depending on the value of the step kind
            // the view to use needs to be set to data
            // or one of the navigation views
            SelectList DataToUse;
            DataToUse = null;
            IQueryable TempData;
            switch (skid)
            {
                case 2: // site (navigation)
                    DataToUse = BuildSitesList(db.Sites);
                    break;
                case 4: // page (navigation)
                    DataToUse = BuildPagesList(db.Pages);
                    break;
                case 6: // field (navigation)
                    DataToUse = BuildFieldsList(db.HTMLFields);
                    break;
                default: // if not one of the defined special cases, use data
                    StepKind temp = db.StepKinds.Find(skid);
                    TempData = db.ViewDataTableVRows.Where(v => v.TableName == temp.DataTable);
                    // now that we've got the data ids, we need to iterate through and build the 'virtual' rows
                    DataToUse = BuildVirtualRows(TempData);
                    break;
            }
            return DataToUse;
        }

        private SelectList BuildVirtualRows(IQueryable Results)
        {

            List<SelectListItem> TempValues = new List<SelectListItem>();
            //TempValues.Add(new SelectListItem() { Text = "", Value = "", Selected = true });

            foreach (ViewDataTableVRow item in Results)
            {
                // pull the DataID and use it to retrieve the corresponding key value pairs
                Dictionary<string, string> TempRow = db.ViewDataTablePerVRows.Where(r => r.DataID == item.DataID).Where(r => r.TableMasterID == item.TableMasterID)
                                        .AsEnumerable()
                                        .ToDictionary(r => r.DataName, r => r.DataValue);
                // convert the data into a select list that can be rendered easily
                Dictionary<string, string> TempObj = new Dictionary<string, string>();
                TempObj.Add("DataID", item.DataID.ToString());
                TempObj.Add("DataValue", "");
                for (int i = 0; i < TempRow.Count; i++)
                {

                    if (i == 0)
                    {
                        TempObj["DataValue"] = TempRow.ElementAt(i).Value;
                    }
                    else
                    {

                        TempObj["DataValue"] = TempObj["DataValue"] + ", " + TempRow.ElementAt(i).Value;
                    }

                }

                TempValues.Add(new SelectListItem() { Text = TempObj["DataID"], Value = TempObj["DataValue"], Selected = false });
            }

            SelectList DataTableRows = new SelectList(TempValues as IEnumerable, "Value", "Text");
            return DataTableRows; // Return the list of data rows
        }


        private SelectList BuildSitesList(IQueryable Results)
        {
            // converts the IQueryable into a select list

            List<SelectListItem> TempValues = new List<SelectListItem>();
            //TempValues.Add(new SelectListItem() { Text = "", Value = "", Selected = true });

            foreach (Site site in Results)
            {
                TempValues.Add(new SelectListItem() { Text = site.DataID.ToString(), Value = site.SiteName, Selected = false });
            }

            return new SelectList(TempValues as IEnumerable, "Value", "Text");
        }

        private SelectList BuildPagesList(IQueryable Results)
        {
            List<SelectListItem> TempValues = new List<SelectListItem>();
            //TempValues.Add(new SelectListItem() { Text = "", Value = "", Selected = true });

            foreach (Page page in Results)
            {
                TempValues.Add(new SelectListItem() { Text = page.PageID.ToString(), Value = page.PageName, Selected = false });
            }
            return new SelectList(TempValues as IEnumerable, "Value", "Text");
        }

        private SelectList BuildFieldsList(IQueryable Results)
        {
            List<SelectListItem> TempValues = new List<SelectListItem>();
            //TempValues.Add(new SelectListItem() { Text = "", Value = "", Selected = true });

            foreach (HTMLField field in Results)
            {
                TempValues.Add(new SelectListItem() { Text = field.FieldID.ToString(), Value = field.FieldName, Selected = false });
            }
            return new SelectList(TempValues as IEnumerable, "Value", "Text");
        }
    }
}